﻿using System;

namespace Hxsoft
{
	/// <summary>
	/// 枚举扩展类。
	/// </summary>
	public static partial class EnumExtensions
	{
		/// <summary>
		/// 解析一个字符串为指定的枚举值，如果解析失败则返回null。
		/// </summary>
		/// <typeparam name="T">解析的目标枚举类型。</typeparam>
		/// <param name="s">进行解析的字符串。</param>
		/// <returns>解析后的枚举值。</returns>
		public static T? ParseOrNull<T>(string s) where T : struct
		{
			if (string.IsNullOrEmpty(s)) return null;

			try
			{
				return (T)Parse(typeof(T), s);
			}
			catch (Exception err)
			{
				return null;
			}
		}

		/// <summary>
		/// 解析一个字符串为指定的枚举值，如果解析失败则返回默认值。
		/// </summary>
		/// <typeparam name="T">解析的目标枚举类型。</typeparam>
		/// <param name="s">进行解析的字符串。</param>
		/// <param name="defaultValue">解析失败时的默认值。</param>
		/// <returns>解析后的枚举值。</returns>
		public static T ParseOrDefault<T>(string s, T defaultValue)
		{
			if (string.IsNullOrEmpty(s)) return defaultValue;

			return (T)Parse(typeof(T), s);
		}

		/// <summary>
		/// 解析一个字符串为指定的枚举值，如果解析失败则返回默认值。
		/// </summary>
		/// <typeparam name="T">解析的目标枚举类型。</typeparam>
		/// <param name="s">进行解析的字符串。</param>
		/// <param name="ignoreCase">解析的字符串忽略大小写。</param>
		/// <param name="defaultValue">解析失败时的默认值。</param>
		/// <returns>解析后的枚举值。</returns>
		public static T ParseOrDefault<T>(string s, bool ignoreCase, T defaultValue)
		{
			if (string.IsNullOrEmpty(s)) return defaultValue;

			return (T)Parse(typeof(T), s, ignoreCase);
		}

		/// <summary>
		/// 转换指定的对象为指定的枚举值，如果转换失败则返回默认值。
		/// </summary>
		/// <typeparam name="T">转换的目标枚举类型。</typeparam>
		/// <param name="from">进行转换的对象。</param>
		/// <returns>转换后的枚举值。</returns>
		public static T ConvertFromOrDefault<T>(object from)
		{
			return ConvertFromOrDefault<T>(from, default(T));
		}

		/// <summary>
		/// 转换指定的对象为指定的枚举值，如果转换失败则返回默认值。
		/// </summary>
		/// <typeparam name="T">转换的目标枚举类型。</typeparam>
		/// <param name="from">进行转换的对象。</param>
		/// <param name="defaultValue">转换失败时的默认值。</param>
		/// <returns>转换后的枚举值。</returns>
		public static T ConvertFromOrDefault<T>(object from, T defaultValue)
		{
			return from == null ? defaultValue : (T)from;
		}
	}
}